<template>
	<div>
		<search ref="search" :search="search" @handleSearch="handleSearch" @handleReset="handleReset" />

		<div class="app-container" style="margin: 3px 15px;">
			<el-alert v-if="tips" :title="tips.content" :type="tips.type" style="margin-bottom: 5px;" />
			<div class="filter-container">
				<!-- 表头的 actions -->
				<component :is="'el-' + item.el" v-for="(item,index) in actions" :key="index" v-action="item.permission"
					:class="item.class" :icon="item.icon" :type="item.type === undefined ? 'primary' : item.type"
					size="mini" style="margin-bottom: 5px;" @click="actionClick(item)">
					{{ item.label }}
				</component>
				<el-button v-if="selectedIds.length > 0 && hidePagination" type="danger" size="small"
					@click="handleDelete(selectedIds)">批量删除</el-button>

				<div class="fr">
					<el-button icon="el-icon-refresh" class="mr-2" size="mini" @click="refreshPage" />
					<el-dropdown :hide-on-click="false">
						<span class="el-dropdown-link">
							<el-button icon="el-icon-menu" size="mini" />
						</span>
						<el-dropdown-menu slot="dropdown">
							<el-dropdown-item v-for="(item, k) in headers" v-if="item.label.length > 0" :key="k">
								<el-checkbox v-model="item.show" /> {{ item.label }}
							</el-dropdown-item>
						</el-dropdown-menu>
					</el-dropdown>
				</div>
			</div>



			<div class="card">
				<el-table stripe :key="updateKey" v-loading="loading" :data="source" style="width: 100%" v-bind="$attrs"
					v-on="getTableEvents"
					:header-cell-style="{background:'#fef0ec',color:'#3a3a3a','font-size' :'12px'}" :border="false"
					:row-class-name="setRowClassName">


					<el-table-column v-for="(item, k) in getHeaders" v-if="item.type !== 'selection'" :key="k"
						v-bind="getAttrsValue(item)">
						<template v-slot="scope">
							<!-- {{isActionOrComponent(getValue(scope, item))}} -->
							 
							 
							<div v-if="isActionOrComponent(getValue(scope, item))">
 
								 
								 
								<component :is="renderTypeList[getMatchRenderFunction(item)].target"
									:cell-list="getValue(scope, item)" :row="scope.row" :parent="getParent"
									:catch-table="getTableObject()" @click.native="($event) => {
              handleNativeClick(getAttrsValue(item), $event)
            }" />
							</div>
							<span v-else>
								{{ getValue(scope, item) }}
							</span>
						</template>

					</el-table-column>
					<el-table-column v-else type="selection" width="50px" :selectable="selectable" />
				</el-table>
			</div>


			<el-row v-if="!hidePagination" justify="end" type="flex">
				<el-col :span="8" style="padding-top: 14px">
					<el-button v-if="this.selectedIds.length > 0" icon="el-icon-delete" style="float: left"
						type="danger" size="small" @click="handleDelete(selectedIds)">批量删除</el-button>
				</el-col>


				<el-col :span="16">
					<el-pagination class="pagination-container" background layout="total, sizes, prev, pager, next"
						:current-page="pagination.currentPage" :page-size="pagination.pageSize"
						:page-sizes="pagination.sizes" :total="pagination.total" @size-change="handleSizeChange"
						@current-change="handlePageChange" />
				</el-col>
			</el-row>

			<el-dialog :title="dialog.title" :visible.sync="dialog.visible" :width="dialogWidth" :modal="dialogModal"
				:show-header="false" :close-on-click-modal="false" class="catch-form" append-to-body
				@opened="dialogOpened" @close="handleHiddenDialog">
				<form-create v-model="formCreate.fApi" :rule="formCreate.rule" :option="form.options"
					:value.sync="formCreate.value" />
			</el-dialog>
		</div>

		<form-create v-show="false" v-model="formCreate.fApi" :rule="[]" />
		<!--- 导入  -->
		<import-excel ref="import" @ok="refreshPage" />
	</div>
</template>

<script>
	import {
		isBoolean,
		isArray
	} from './type'
	import operate from './mixin/operete'

	// components
	import ElementsMapping from './components/ElementsMapping'
	import ComponentsMapping from './components/ComponentsMapping'
	import search from './components/Search'
	import importExcel from './components/Import'
	// mixins
	import create from './mixin/create'
	import update from './mixin/update'
	import del from './mixin/del'
	import view from './mixin/view'
	import to from './mixin/to'
	import _export from './mixin/export'
	import excel from './mixin/excel'
	import props from './mixin/props'
	import tableData from './mixin/tableData'

	export default {
		name: 'Table',
		components: {
			ElementsMapping,
			ComponentsMapping,
			search,
			importExcel
		},
		mixins: [operate, create, update, del, view, to, _export, excel, props, tableData],
		computed: {
			// 获取可用 refs 为止
			getParent() {
				let parent = this.$parent

				while (!Object.keys(parent.$refs).length) {
					parent = parent.$parent
				}
				return parent
			},
			// 搜索参数
			queryParams() {
				return this.$refs.search.queryParams
			},
			getTableEvents() {
				const events = this.tableEvents
				for (const key in events) {
					events[key] = this[events[key]]
				}
				return events
			},
			getForm() {
				return this.formCreate.fApi
			},

			// headers
			getHeaders() {

				return this.headers.filter(header => header.show)
			}
		},
		methods: {
			setRowClassName(row) {
				// 自定义行高为 50px
				return 'custom-row-height';
			},
			getAttrsValue(item) {
				const {
					attrs
				} = {
					attrs: item
				}
				return {
					...attrs
				}
				// delete result.prop
				// return result
			},
			dialogOpened() {
				this.getForm.clearValidateState()
				// 表单渲染后的操作
				this.dialogOpenedFirstDo()

				this.getForm.refresh()
				// 创建时候填充数据
				if (this.form.isCreatedFillData) {
					this.getForm.setValue(this.form.data)
				}
				// 创建时
				if (this.form.data === null) {
					this.getForm.resetFields()
				} else {
					// 更新时
					this.getForm.setValue(this.form.data)
				}
				// 渲染完成之后钩子
				if (this.getParent.renderAfter !== undefined) {

					this.getParent.renderAfter(this.form.data)
				}
			},
			dialogOpenedFirstDo() {
				// 创建前操作
				if (this.getParent.beforeCreate !== undefined) {
					this.getParent.beforeCreate()
				}

				// 更新前数据操作
				if (this.form.data && this.getParent.beforeUpdate !== undefined) {
					this.getParent.beforeUpdate(this.form.data)
				}
			},
			getValue(scope, configItem) {
				const prop = configItem.prop
				const renderName = this.getMatchRenderFunction(configItem)
				const renderObj = this.renderTypeList[renderName]
				if (renderObj !== undefined) {
					return configItem[renderName]
					/** return renderObj.target
					  ? this.getRenderValue(scope, configItem, { name: renderName, type: 'bind' })
					  : this.getRenderValue(scope, configItem)*/
				}
				return scope.row[prop]
			},
			getRenderValue(scope, item, fn = {
				name: 'render',
				type: 'call'
			}) {
				const prop = item.prop
				const propValue = prop && scope.row[prop]
				// this.$set(scope.row, '$index', scope.$index)
				const args = propValue !== undefined ? propValue : scope.row
				return item[fn.name][fn.type](this.getParent, args)
			},
			// 匹配 render 开头的函数
			getMatchRenderFunction(obj) {
				return Object.keys(obj).find((key) => {
					if (key === 'action' || key === 'component') {
						return key
					}
				})
			},
			isActionOrComponent($item) {
				return isArray($item)
			},
			stopBubbles(e) {
				const event = e || window.event
				if (event && event.stopPropagation) {
					event.stopPropagation()
				} else {
					event.cancelBubble = true
				}
			},
			handleNativeClick({
				isBubble
			}, e) {
				// 考虑到单元格内渲染了组件，并且组件自身可能含有点击事件，故添加了阻止冒泡机制
				// 若指定 isBubble 为 false，则当前单元格恢复冒泡机制
				if (
					isBoolean(isBubble) &&
					!isBubble
				) return
				this.stopBubbles(e)
			},
			// 获取 table 对象
			getTableObject() {
				return this
			},
			refreshPage() {
				this.getParent.getTableFrom()
			},
			// 表头按钮事件触发
			actionClick(item) {
				// 如果没有路由跳转 触发事件
				if (item.route === undefined) {
					if (this[item.click] === undefined) {
						this.getParent[item.click]()
					} else {
						this[item.click]()
					}
				} else {
					// 路由跳转
					this.$router.push(item.route)
				}
			},
			handleImport() {
				this.$refs.import.handleImport()
			}
		}
	}
</script>

<style lang="scss">
	.el-table .el-table__row {
		height: 22px;
	}

	.custom-row-height {
		height: 20px !important;
	}

	.search-container {
		margin: 5px 15px;
		background: white;
	}

	._import_ {
		.el-dialog__body {
			padding: 5px 20px 60px 20px;
		}

		.el-divider {
			margin: 8px 0;
		}
	}

	.search-form {
		// padding-bottom: 20px;
		text-align: right;

		.filter-item {
			display: inline-block;
			vertical-align: middle;
			margin-top: 3px;
		}

		.form-search-input {
			width: 200px;
			margin-right: 5px;
		}

		.reset,
		.search,
		.multi-delete {
			padding-left: 10px;
			padding-right: 10px;
		}
	}

	.table-list-container {
		.table-pagination {
			padding-top: 20px;
		}

		.header {
			display: flex;
			padding-bottom: 20px;

			.header-actions {
				flex: 1;
				overflow-x: auto;

				.overflow-box {
					display: flex;
					flex-direction: row-reverse;
					overflow-x: auto;
					white-space: nowrap;

					.el-button:nth-child(1) {
						margin-left: 10px;
					}
				}
			}
		}

		.el-table {
			th {
				font-size: 14px;
			}

			td {
				font-size: 14px;
			}
		}
	}
</style>